package com.huaxin.hxmodulestatisticalanalysis.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huaxin.hxmodulestatisticalanalysis.dto.response.*;
import com.huaxin.hxmodulestatisticalanalysis.mapper.*;
import com.huaxin.hxmodulestatisticalanalysis.models.*;
import com.huaxin.hxmodulestatisticalanalysis.service.DataAnalysisService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@RequiredArgsConstructor
@Slf4j
public class DataAnalysisServiceImpl extends ServiceImpl<DeviceDataCollectionWideMapper, DeviceDataCollectionWide> implements DataAnalysisService {
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private final AlarmMapper alarmMapper;
    private final DeviceInstanceMapper deviceInstanceMapper;
    private final ElectricalRoomMapper electricalRoomMapper;
    private final SwitchCabinetMapper switchCabinetMapper;


    @Override
    public List<VoltageCurrentTrendVO> getVoltageCurrentTrendLast24Hours(Map<String, Object> params) {
        // 定义目标设备类型
        List<String> deviceTypes = Arrays.asList("power_meter_10kv", "power_meter_04kv");
        params.putIfAbsent("deviceTypes", deviceTypes);
        return this.baseMapper.getVoltageCurrentTrendLast24Hours(params);
    }

    @Override
    public List<PowerComparisonVO> getPowerComparisonLastHour(Map<String, Object> params) {
        // 默认设备类型
        List<String> deviceTypes = Arrays.asList("power_meter_10kv", "power_meter_04kv");
        params.putIfAbsent("deviceTypes", deviceTypes);
        return baseMapper.getPowerComparisonLastHour(params);
    }

    @Override
    public List<PowerFactorTrendVO> getPowerFactorTrend(Map<String, Object> params) {
        List<String> deviceTypes = Arrays.asList("power_meter_10kv", "power_meter_04kv");
        params.putIfAbsent("deviceTypes", deviceTypes);
        return baseMapper.selectPowerFactorTrend(params);
    }

    @Override
    public List<EnergyAccumulationTrendVO> getEnergyAccumulationTrend(Map<String, Object> params) {
        List<String> deviceTypes = Arrays.asList("power_meter_10kv", "power_meter_04kv");
        params.putIfAbsent("deviceTypes", deviceTypes);
        return baseMapper.selectEnergyAccumulationTrend(params);
    }

    @Override
    public List<EnergyIncrementVO> getEnergyIncrementData(Map<String, Object> params) {
        List<String> deviceTypes = Arrays.asList("power_meter_10kv", "power_meter_04kv");
        params.putIfAbsent("deviceTypes", deviceTypes);
        return baseMapper.getEnergyIncrementData(params);
    }

    @Override
    public List<PeakValleyFlatStatsVO> getPeakValleyFlatStats(Map<String, Object> params) {
        List<String> deviceTypes = Arrays.asList("power_meter_10kv", "power_meter_04kv");
        params.putIfAbsent("deviceTypes", deviceTypes);
        return baseMapper.selectPeakValleyFlatStats(params);
    }

    @Override
    public List<ThreePhaseUnbalanceVO> getThreePhaseUnbalanceData(Map<String, Object> params) {
        List<String> deviceTypes = Arrays.asList("power_meter_10kv", "power_meter_04kv");
        params.putIfAbsent("deviceTypes", deviceTypes);
        return baseMapper.selectThreePhaseUnbalanceData(params);
    }

    @Override
    public List<LoadRateStatsVO> getDailyLoadRate(Map<String, Object> params) {
        List<Map<String, Object>> result = baseMapper.selectDailyLoadRate(params);
        return convertToVO(result);
    }

    @Override
    public List<LoadRateStatsVO> getPeriodLoadRate(Map<String, Object> params) {
        List<Map<String, Object>> result = baseMapper.selectPeriodLoadRate(params);
        return convertToVO(result);
    }

    @Override
    public List<LoadRateStatsVO> getOverloadedDevices(Map<String, Object> params) {
        params.putIfAbsent("limit", 10); // 默认Top10
        List<Map<String, Object>> result = baseMapper.selectOverloadedDevices(params);
        return convertToVO(result);
    }

    private List<LoadRateStatsVO> convertToVO(List<Map<String, Object>> maps) {
        return maps.stream().map(m -> {
            LoadRateStatsVO vo = new LoadRateStatsVO();
            vo.setDeviceId((Long) m.get("device_id"));
            vo.setOrgId((String) m.get("org_id"));
            Object dateObj = m.get("date");
            if (dateObj instanceof LocalDateTime) {
                vo.setDate((LocalDateTime) dateObj);
            }
            vo.setPeriodType((String) m.get("period_type"));
            vo.setAvgPowerKw((BigDecimal) m.get("avg_power_kw"));
            vo.setMaxPowerKw((BigDecimal) m.get("max_power_kw"));
            vo.setLoadRatePercent((BigDecimal) m.get("load_rate_percent"));
            vo.setDataCount((Long) m.get("data_count")); // ✅ 改为 (Long)
            return vo;
        }).collect(Collectors.toList());
    }


    @Override
    public List<DailyEnergyRankingDTO> getDailyEnergyRanking(
            String date,
            String orgId,
            Long stationNumber,
            Integer limit) {

        // 1. 校验日期
        if (date == null || date.trim().isEmpty()) {
            throw new IllegalArgumentException("统计日期不能为空");
        }
        LocalDate localDate;
        try {
            localDate = LocalDate.parse(date.trim(), DATE_FORMATTER);
        } catch (Exception e) {
            throw new IllegalArgumentException("日期格式错误，正确格式为：yyyy-MM-dd", e);
        }

        // 2. 构建时间范围
        LocalDateTime startTime = localDate.atStartOfDay();
        LocalDateTime endTime = localDate.atTime(23, 59, 59);


        // 4. 构建参数
        Map<String, Object> params = new HashMap<>();
        List<String> deviceTypes = Arrays.asList("power_meter_10kv", "power_meter_04kv");
        params.putIfAbsent("deviceTypes", deviceTypes);
        params.put("deviceTypes", deviceTypes);
        params.put("startTime", startTime.format(DATETIME_FORMATTER));
        params.put("endTime", endTime.format(DATETIME_FORMATTER));
        params.put("orgId", orgId);
        params.put("stationNumber", stationNumber);
        params.put("limit", limit != null && limit > 0 ? limit : 10);

        // 5. 查询原始数据（Map 形式）
        List<Map<String, Object>> resultMapList = baseMapper.selectDailyEnergyConsumption(params);

        // 6. 转换为 DTO 列表
        return resultMapList.stream().map(map -> {
            DailyEnergyRankingDTO dto = new DailyEnergyRankingDTO();

            dto.setDeviceId((Long) map.get("device_id"));
            dto.setOrgId((String) map.get("org_id"));
            dto.setStationNumber((Long) map.get("station_number"));

            Object dailyEnergyObj = map.get("daily_energy_kwh");
            dto.setDailyEnergyKwh(dailyEnergyObj != null ? new BigDecimal(dailyEnergyObj.toString()) : null);

            Object startReadingObj = map.get("start_reading_kwh");
            dto.setStartReadingKwh(startReadingObj != null ? new BigDecimal(startReadingObj.toString()) : null);

            Object endReadingObj = map.get("end_reading_kwh");
            dto.setEndReadingKwh(endReadingObj != null ? new BigDecimal(endReadingObj.toString()) : null);

            dto.setDataCount((Long) map.get("data_count"));

            Object avgPowerObj = map.get("avg_power_kw_est");
            dto.setAvgPowerKwEst(avgPowerObj != null ? new BigDecimal(avgPowerObj.toString()) : null);

            dto.setDate(date); // 设置统计日期

            return dto;
        }).collect(Collectors.toList());
    }

    @Override
    public List<TemperatureHumidityData> getTemperatureHumidityTrend(
            String familyId,
            String orgId,
            Long deviceId,
            Long stationNumber) {

        List<String> deviceTypes = Arrays.asList("env_monitor_room");

        return baseMapper.getTemperatureHumidityTrend(deviceTypes, familyId, orgId, deviceId, stationNumber);
    }

    @Override
    public AlarmStatusData getAlarmStatus(
            String familyId,
            String orgId,
            Long deviceId,
            Long stationNumber) {


        List<String> deviceTypes = Arrays.asList("env_monitor_room");
        Map<String, Object> params = new HashMap<>();
        params.put("deviceTypes", deviceTypes);
        params.put("familyId", familyId);
        params.put("orgId", orgId);
        params.put("deviceId", deviceId);
        params.put("stationNumber", stationNumber);

        AlarmStatusData result = baseMapper.selectLatestAlarmStatus(params);

        // 如果没有查到数据，返回默认“正常”
        if (result == null) {
            result = new AlarmStatusData();
            result.setSmokeAlarm(false);
            result.setWaterAlarm(false);
            result.setIntrusionAlarm(false);
        }

        return result;
    }

    @Override
    public List<TemperatureHeatmapItem> getTemperatureHeatmapData(
            String orgId,
            String familyId) {

        List<String> deviceTypes = Arrays.asList("env_monitor_room");

        Map<String, Object> params = new HashMap<>();
        params.put("deviceTypes", deviceTypes);
        params.put("orgId", orgId);
        params.put("familyId", familyId);

        return baseMapper.selectTemperatureHeatmapData(params);
    }

    /**
     * 获取湿度热力图数据
     */
    public List<HumidityHeatmapData> getHumidityHeatmapData(String orgId,
                                                            String familyId) {
        List<String> deviceTypes = Arrays.asList("env_monitor_room");
        Map<String, Object> params = new HashMap<>();
        params.put("deviceTypes", deviceTypes);
        params.put("orgId", orgId);
        params.put("familyId", familyId);

        return baseMapper.selectHumidityHeatmapData(params);
    }

    // 白名单：允许的微机保护断路器字段名
    private static final String[] VALID_BREAKER_FIELDS = {
            "breaker_1_status",
            "breaker_2_status",
            "breaker_3_status"
    };

    @Override
    public List<BreakerStatusRecord> getBreakerStatusHistory(
            String orgId,
            Long stationNumber,
            Long deviceId,
            Integer breakerNum,
            LocalDateTime startTime,
            LocalDateTime endTime) {

        // 参数校验
        if (orgId == null || deviceId == null || breakerNum == null) {
            throw new IllegalArgumentException("组织ID、设备ID、断路器编号不能为空");
        }

        if (breakerNum < 1 || breakerNum > 3) {
            throw new IllegalArgumentException("断路器编号必须为 1, 2 或 3");
        }

        if (startTime == null) {
            startTime = LocalDateTime.now().minusHours(24);
        }
        if (endTime == null) {
            endTime = LocalDateTime.now();
        }

        if (startTime.isAfter(endTime)) {
            throw new IllegalArgumentException("开始时间不能晚于结束时间");
        }
        // 构造字段名（注意大小写！）
        String breakerField = "breaker_" + breakerNum + "_status";
        // 安全校验
        boolean isValid = false;
        for (String field : VALID_BREAKER_FIELDS) {
            if (Objects.equals(field, breakerField)) {
                isValid = true;
                break;
            }
        }
        if (!isValid) {
            throw new IllegalArgumentException("非法的断路器字段名");
        }

        // 查询数据库
        return baseMapper.selectBreakerStatusHistory(orgId, stationNumber, deviceId, breakerField, startTime, endTime);
    }


    /**
     * 分析断路器状态历史，找出可能的跳闸事件（特别是过流跳闸）
     */
    @Override
    public List<TripEvent> analyzeTripEvents(List<BreakerStatusRecord> records, BigDecimal currentThreshold,
                                             Long timeWindowSeconds) {
        List<TripEvent> tripEvents = new ArrayList<>();

        if (records == null || records.size() < 2) {
            return tripEvents;
        }

        // 排序确保时间顺序（前端已排序，这里再保险一次）
        records.sort((a, b) -> a.getCreatedAt().compareTo(b.getCreatedAt()));

        BreakerStatusRecord previous = null;

        for (BreakerStatusRecord current : records) {
            if (previous == null) {
                previous = current;
                continue;
            }

            // 检查是否发生分闸（closed → open）
            if ("closed".equalsIgnoreCase(previous.getBreakerStatus()) &&
                    "open".equalsIgnoreCase(current.getBreakerStatus())) {

                // 计算时间差
                Duration gap = Duration.between(previous.getCreatedAt(), current.getCreatedAt());
                if (gap.getSeconds() > timeWindowSeconds) {
                    // 跳过长时间间隔的状态变化（可能不是实时跳闸）
                    previous = current;
                    continue;
                }

                // 查找跳闸前的电流峰值
                BigDecimal peakCurrent = findPeakCurrentBefore(records, current.getCreatedAt());

                if (peakCurrent != null && peakCurrent.compareTo(currentThreshold) >= 0) {
                    TripEvent event = new TripEvent(
                            current.getCreatedAt(),   // 跳闸时间
                            current.getDeviceId(),
                            current.getStationNumber()
                    );
                    event.setType(TripEvent.TripType.OVER_CURRENT);
                    event.setPreCurrent(previous.getCurrentAa());
                    event.setPeakCurrent(peakCurrent);
                    event.setDescription(String.format(
                            "检测到过流跳闸：峰值电流 %.2fA ≥ %.2fA 阈值，在 %d 秒内发生分闸。",
                            peakCurrent, currentThreshold, gap.getSeconds()
                    ));
                    tripEvents.add(event);
                }
            }
            previous = current;
        }

        return tripEvents;
    }

    /**
     * 在指定时间点之前的一小段时间内查找最大电流值
     */
    private BigDecimal findPeakCurrentBefore(List<BreakerStatusRecord> records, LocalDateTime tripTime) {
        LocalDateTime lookBack = tripTime.minusSeconds(60);
        BigDecimal peak = null;

        for (int i = records.size() - 1; i >= 0; i--) {
            BreakerStatusRecord r = records.get(i);
            if (r.getCreatedAt().isAfter(tripTime)) continue;
            if (r.getCreatedAt().isBefore(lookBack)) break;

            BigDecimal current = r.getCurrentAa();
            if (current != null && (peak == null || current.compareTo(peak) > 0)) {
                peak = current;
            }
        }

        return peak == null ? BigDecimal.ZERO : peak;
    }

    @Override
    public List<ThreePhaseTemperatureDTO> getThreePhaseTemperatureTrend(
            Long deviceId,
            String familyId,
            String orgId,
            Long stationNumber,
            LocalDateTime startTime,
            LocalDateTime endTime) {
        List<String> deviceTypes = Arrays.asList("transformer_temp_controller");
        Map<String, Object> params = new HashMap<>();
        params.put("deviceTypes", deviceTypes);
        params.put("deviceId", deviceId);
        params.put("familyId", familyId);
        params.put("orgId", orgId);
        params.put("stationNumber", stationNumber);
        params.put("startTime", startTime);
        params.put("endTime", endTime);

        return baseMapper.selectTransformerTemperatures(params);
    }

    public Map<String, Object> getMultiTransformerTemperatureComparison(
            String orgId,
            Long stationNumber) {

        // 固定设备类型（可配置）
        List<String> deviceTypes = Arrays.asList("transformer_temp_controller");

        // 调用 Mapper（传入四个参数，不是 Map）
        List<Map<String, Object>> rawData = baseMapper.selectMultiTransformerAvgTemperatures(
                deviceTypes,
                orgId,
                stationNumber
        );

        // 后续处理不变
        List<TemperatureComparisonDTO> data = rawData.stream().map(row -> {
            TemperatureComparisonDTO dto = new TemperatureComparisonDTO();
            dto.setDeviceId((Long) row.get("device_id"));
            dto.setDeviceType((String) row.get("device_type"));
            dto.setStationNumber((Long) row.get("station_number"));
            dto.setAvgTempA((BigDecimal) row.get("avgTempA"));
            dto.setAvgTempB((BigDecimal) row.get("avgTempB"));
            dto.setAvgTempC((BigDecimal) row.get("avgTempC"));
            dto.setDeviceLabel("站点" + dto.getStationNumber() + "-设备" + dto.getDeviceId());
            return dto;
        }).collect(Collectors.toList());

        // 构造 ECharts 数据
        Map<String, Object> result = new HashMap<>();
        result.put("deviceInfo", data);

        List<String> categories = data.stream()
                .map(TemperatureComparisonDTO::getDeviceLabel)
                .collect(Collectors.toList());

        List<BigDecimal> tempAList = data.stream().map(TemperatureComparisonDTO::getAvgTempA).collect(Collectors.toList());
        List<BigDecimal> tempBList = data.stream().map(TemperatureComparisonDTO::getAvgTempB).collect(Collectors.toList());
        List<BigDecimal> tempCList = data.stream().map(TemperatureComparisonDTO::getAvgTempC).collect(Collectors.toList());

        result.put("categories", categories);
        result.put("series", Arrays.asList(
                createSeries("A相温度", tempAList),
                createSeries("B相温度", tempBList),
                createSeries("C相温度", tempCList)
        ));

        return result;
    }

    private Map<String, Object> createSeries(String name, List<?> data) {
        Map<String, Object> series = new HashMap<>();
        series.put("name", name);
        series.put("type", "bar");
        series.put("data", data);
        series.put("itemStyle", Map.of("borderRadius", 4));
        return series;
    }

    @Override
    public Map<String, Object> getWirelessHostCableTempTrend(
            String orgId,
            List<Long> deviceIds,
            Long stationNumber) {

        // 执行查询
        List<Map<String, Object>> rawData = baseMapper.selectWirelessHostCableTempTrend(
                orgId, deviceIds, stationNumber
        );

        // 转换为 DTO 列表
        List<CableTemperatureTrendDTO> data = rawData.stream().map(row -> {
            CableTemperatureTrendDTO dto = new CableTemperatureTrendDTO();
            dto.setDeviceId((Long) row.get("device_id"));

            // 解析时间桶
            String timeStr = (String) row.get("time_bucket");
            dto.setTime(LocalDateTime.parse(timeStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

            dto.setTempA((BigDecimal) row.get("avgCableTempA"));
            dto.setTempB((BigDecimal) row.get("avgCableTempB"));
            dto.setTempC((BigDecimal) row.get("avgCableTempC"));

            // 生成设备标签
            dto.setDeviceLabel("设备" + dto.getDeviceId());

            return dto;
        }).collect(Collectors.toList());

        // 按设备分组
        Map<Long, List<CableTemperatureTrendDTO>> groupedByDevice = data.stream()
                .collect(Collectors.groupingBy(CableTemperatureTrendDTO::getDeviceId));

        // 准备返回结构
        Map<String, Object> result = new HashMap<>();
        result.put("data", data);

        // 所有唯一时间点（排序）
        List<String> timeList = data.stream()
                .map(dto -> dto.getTime().format(DateTimeFormatter.ofPattern("HH:mm")))
                .distinct()
                .sorted()
                .collect(Collectors.toList());

        result.put("timeList", timeList);

        // 每个设备的三相温度序列
        List<Map<String, Object>> seriesList = new ArrayList<>();

        for (Map.Entry<Long, List<CableTemperatureTrendDTO>> entry : groupedByDevice.entrySet()) {
            Long deviceId = entry.getKey();
            List<CableTemperatureTrendDTO> list = entry.getValue();

            // 排序
            list.sort(Comparator.comparing(CableTemperatureTrendDTO::getTime));

            // 提取温度列表
            List<BigDecimal> tempA = list.stream().map(CableTemperatureTrendDTO::getTempA).collect(Collectors.toList());
            List<BigDecimal> tempB = list.stream().map(CableTemperatureTrendDTO::getTempB).collect(Collectors.toList());
            List<BigDecimal> tempC = list.stream().map(CableTemperatureTrendDTO::getTempC).collect(Collectors.toList());

            seriesList.add(createSeries("设备" + deviceId + "-A相", timeList, tempA));
            seriesList.add(createSeries("设备" + deviceId + "-B相", timeList, tempB));
            seriesList.add(createSeries("设备" + deviceId + "-C相", timeList, tempC));
        }

        result.put("series", seriesList);
        return result;
    }

    private Map<String, Object> createSeries(String name, List<String> timeList, List<BigDecimal> data) {
        Map<String, Object> series = new HashMap<>();
        series.put("name", name);
        series.put("type", "line");
        series.put("data", data);
        series.put("smooth", true); // 平滑曲线
        series.put("emphasis", Map.of("focus", "series"));
        return series;
    }
    // DataAnalysisServiceImpl.java

    @Override
    public Map<String, Object> getCableTemperatureTop10(String orgId, Long stationNumber) {
        List<Map<String, Object>> rawList = baseMapper.selectCableTempTop10(orgId, stationNumber);

        Map<Long, TempRankingDTO> deviceLatest = new HashMap<>();

        for (Map<String, Object> row : rawList) {
            Long deviceId = (Long) row.get("device_id");
            BigDecimal tempValue = (BigDecimal) row.get("temp_value");
            LocalDateTime tempTime = (LocalDateTime) row.get("temp_time");

            TempRankingDTO existing = deviceLatest.get(deviceId);
            if (existing == null || tempValue.compareTo(existing.getMaxTemp()) > 0) {
                TempRankingDTO dto = new TempRankingDTO();
                dto.setDeviceId(deviceId);
                dto.setOrgId((String) row.get("org_id"));
                dto.setStationNumber((Long) row.get("station_number"));
                dto.setMaxTemp(tempValue);
                dto.setMaxTempTime(tempTime);

                // 填充设备信息（可能为 null）
                dto.setDeviceName((String) row.get("device_name"));
                dto.setZoneName((String) row.get("zone_name"));
                dto.setInstallLocation((String) row.get("install_location"));
                dto.setStatus((String) row.get("status"));
                dto.setSerialNumber((String) row.get("serial_number"));

                // 构造前端显示标签
                if (dto.getDeviceName() != null) {
                    dto.setDeviceLabel(dto.getDeviceName() + " (" + deviceId + ")");
                } else {
                    dto.setDeviceLabel("设备" + deviceId);
                }

                deviceLatest.put(deviceId, dto);
            }
        }

        // 按温度降序
        List<TempRankingDTO> sortedList = new ArrayList<>(deviceLatest.values());
        sortedList.sort((a, b) -> b.getMaxTemp().compareTo(a.getMaxTemp()));

        // 取 Top10
        List<TempRankingDTO> top10 = sortedList.stream()
                .limit(10)
                .collect(Collectors.toList());

        // 添加排名
        for (int i = 0; i < top10.size(); i++) {
            top10.get(i).setRank(i + 1);
        }

        Map<String, Object> result = new HashMap<>();
        result.put("total", top10.size());
        result.put("data", top10);

        return result;
    }


    @Override
    public Map<String, Object> getEnterpriseKpiCards(String orgId) {
        List<Map<String, Object>> latestData = baseMapper.selectLatestByOrgId(orgId);
        List<KpiCardDTO> cards = new ArrayList<>();

        if (latestData.isEmpty()) {
            // 即使没有数据，也返回 6 张默认卡片
            return buildResult(createDefaultKpiCards());
        }

        // 构建设备 auto_id -> 名称映射（使用 device_name 字段）
        Map<Long, String> deviceNameMap = latestData.stream()
                .filter(m -> m.get("auto_id") != null && m.get("device_name") != null)
                .collect(Collectors.toMap(
                        m -> toLong(m.get("auto_id")), // 安全转换 Integer/Long → Long
                        m -> (String) m.get("device_name"),
                        (a, b) -> a // 重复取第一个
                ));

        Function<Long, String> getDeviceName = id -> deviceNameMap.getOrDefault(id, "未知设备");

        // 获取当前时间作为 fallback 时间戳
        LocalDateTime now = LocalDateTime.now();

        // ==================== 1. 最大相电流 ====================
        Optional<PhaseValue> maxCurrentOpt = latestData.stream()
                .filter(m -> {
                    String type = (String) m.get("device_type");
                    return "power_meter_10kv".equals(type) || "power_meter_04kv".equals(type) || "microprocessor_relay".equals(type);
                })
                .flatMap(m -> Stream.of(
                        new PhaseValue(getBigDecimal(m, "current_a_a"), "A相", m),
                        new PhaseValue(getBigDecimal(m, "current_b_a"), "B相", m),
                        new PhaseValue(getBigDecimal(m, "current_c_a"), "C相", m)
                ))
                .filter(p -> p.value.compareTo(BigDecimal.ZERO) > 0)
                .max(Comparator.comparing(p -> p.value.doubleValue()));

        maxCurrentOpt.ifPresentOrElse(
                p -> {
                    Long autoId = toLong(p.source.get("auto_id"));
                    String deviceName = getDeviceName.apply(autoId);
                    LocalDateTime ts = (LocalDateTime) p.source.get("created_at");

                    cards.add(createCard("最大相电流", round(p.value), "A", deviceName, p.phase, ts));
                },
                () -> cards.add(createCard("最大相电流", BigDecimal.ZERO, "A", "无", "无", now))
        );

        // ==================== 2. 总有功功率 ====================
        Optional<Map<String, Object>> powerOpt = latestData.stream()
                .filter(m -> {
                    String type = (String) m.get("device_type");
                    return "power_meter_04kv".equals(type) || "power_meter_10kv".equals(type) || "microprocessor_relay".equals(type);
                })
                .filter(m -> {
                    String name = (String) m.get("device_name");
                    return name == null || name.contains("总") || name.contains("进线");
                })
                .max(Comparator.comparing(m -> getBigDecimal(m, "active_power_total_kw").abs().doubleValue()));

        powerOpt.ifPresentOrElse(
                m -> {
                    Long autoId = toLong(m.get("auto_id"));
                    String deviceName = getDeviceName.apply(autoId);
                    LocalDateTime ts = (LocalDateTime) m.get("created_at");
                    BigDecimal power = getBigDecimal(m, "active_power_total_kw");

                    cards.add(createCard("总有功功率", round(power), "kW", deviceName, null, ts));
                },
                () -> cards.add(createCard("总有功功率", BigDecimal.ZERO, "kW", "无", null, now))
        );

        // ==================== 3. 电缆最高温度 ====================
        Optional<PhaseValue> cableTempOpt = latestData.stream()
                .filter(m -> "wireless_temp_host".equals(m.get("device_type")))
                .flatMap(m -> Stream.of(
                        new PhaseValue(getBigDecimal(m, "cable_temp_a"), "A相", m),
                        new PhaseValue(getBigDecimal(m, "cable_temp_b"), "B相", m),
                        new PhaseValue(getBigDecimal(m, "cable_temp_c"), "C相", m)
                ))
                .filter(p -> p.value.compareTo(BigDecimal.ZERO) > 0)
                .max(Comparator.comparing(p -> p.value.doubleValue()));

        cableTempOpt.ifPresentOrElse(
                p -> {
                    String deviceName = (String) p.source.get("device_name");
                    LocalDateTime ts = (LocalDateTime) p.source.get("created_at");
                    cards.add(createCard("电缆最高温度", round(p.value), "℃", deviceName, p.phase, ts));
                },
                () -> cards.add(createCard("电缆最高温度", BigDecimal.ZERO, "℃", "无", "无", now))
        );

        // ==================== 4. 变压器温度 ====================
        Optional<PhaseValue> transTempOpt = latestData.stream()
                .filter(m -> "transformer_temp_controller".equals(m.get("device_type")))
                .flatMap(m -> Stream.of(
                        new PhaseValue(getBigDecimal(m, "transformer_temp_a"), "A相绕组", m),
                        new PhaseValue(getBigDecimal(m, "transformer_temp_b"), "B相绕组", m),
                        new PhaseValue(getBigDecimal(m, "transformer_temp_c"), "C相绕组", m)
                ))
                .filter(p -> p.value.compareTo(BigDecimal.ZERO) > 0)
                .max(Comparator.comparing(p -> p.value.doubleValue()));

        transTempOpt.ifPresentOrElse(
                p -> {
                    String deviceName = (String) p.source.get("device_name");
                    LocalDateTime ts = (LocalDateTime) p.source.get("created_at");
                    cards.add(createCard("变压器温度", round(p.value), "℃", deviceName, p.phase, ts));
                },
                () -> cards.add(createCard("变压器温度", BigDecimal.ZERO, "℃", "无", "无", now))
        );

        // ==================== 5. 当前告警数 ====================
        Integer alarmCount = alarmMapper.countUnresolvedAlarms(orgId);
        int count = alarmCount != null ? alarmCount : 0;

        LocalDateTime lastAlarmTime = alarmMapper.getLastUnresolvedAlarmTime(orgId);
        LocalDateTime alarmTs = lastAlarmTime != null ? lastAlarmTime : now;

        KpiCardDTO alarmCard = new KpiCardDTO();
        alarmCard.setTitle("当前告警数");
        alarmCard.setValue(BigDecimal.valueOf(count));
        alarmCard.setUnit("条");
        alarmCard.setDeviceName("系统");
        alarmCard.setSuffix(count > 0 ? "未恢复" : "正常");
        alarmCard.setTimestamp(alarmTs);
        cards.add(alarmCard);

        // ==================== 6. 环境温度 ====================
        Optional<Map<String, Object>> envOpt = latestData.stream()
                .filter(m -> "env_monitor_room".equals(m.get("device_type")))
                .max(Comparator.comparing(m -> (LocalDateTime) m.get("created_at")));

        envOpt.ifPresentOrElse(
                m -> {
                    BigDecimal temp = getBigDecimal(m, "temperature_room");
                    String deviceName = (String) m.get("device_name");
                    LocalDateTime ts = (LocalDateTime) m.get("created_at");
                    cards.add(createCard("环境温度", round(temp), "℃", deviceName, null, ts));
                },
                () -> cards.add(createCard("环境温度", BigDecimal.ZERO, "℃", "无", null, now))
        );

        // 按固定顺序排序并限制 6 条
        List<String> order = Arrays.asList(
                "最大相电流",
                "总有功功率",
                "电缆最高温度",
                "变压器温度",
                "当前告警数",
                "环境温度"
        );

        List<KpiCardDTO> sorted = cards.stream()
                .sorted(Comparator.comparing(c -> order.indexOf(c.getTitle())))
                .limit(6)
                .collect(Collectors.toList());

        return buildResult(sorted);
    }

    // 辅助方法：创建卡片
    private KpiCardDTO createCard(String title, BigDecimal value, String unit,
                                  String deviceName, String suffix, LocalDateTime timestamp) {
        KpiCardDTO card = new KpiCardDTO();
        card.setTitle(title);
        card.setValue(value);
        card.setUnit(unit);
        card.setDeviceName(deviceName);
        card.setSuffix(suffix);
        card.setTimestamp(timestamp);
        return card;
    }

    // 安全获取 BigDecimal，null 返回 ZERO
    private BigDecimal getBigDecimal(Map<String, Object> map, String key) {
        Object val = map.get(key);
        if (val instanceof BigDecimal) {
            return (BigDecimal) val;
        } else if (val instanceof Number) {
            return new BigDecimal(((Number) val).doubleValue());
        } else {
            return BigDecimal.ZERO;
        }
    }

    // 构建返回结果
    private Map<String, Object> buildResult(List<KpiCardDTO> cards) {
        Map<String, Object> result = new HashMap<>();
        result.put("total", cards.size());
        result.put("data", cards);
        return result;
    }

    // 内部类：带相位信息的数值
    private static class PhaseValue {
        BigDecimal value;
        String phase;
        Map<String, Object> source;

        PhaseValue(BigDecimal value, String phase, Map<String, Object> source) {
            this.value = value;
            this.phase = phase;
            this.source = source;
        }
    }

    private Long toLong(Object obj) {
        if (obj == null) return null;
        if (obj instanceof Number) {
            return ((Number) obj).longValue();
        }
        if (obj instanceof String) {
            try {
                return Long.parseLong((String) obj);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }

    // 四舍五入到 2 位小数
    private BigDecimal round(BigDecimal value) {
        return value.setScale(2, BigDecimal.ROUND_HALF_UP);
    }

    // 创建默认卡片列表（当 latestData 为空时使用）
    private List<KpiCardDTO> createDefaultKpiCards() {
        LocalDateTime now = LocalDateTime.now();
        BigDecimal zero = BigDecimal.ZERO;
        List<KpiCardDTO> defaults = new ArrayList<>();

        defaults.add(createCard("最大相电流", zero, "A", "无", "无", now));
        defaults.add(createCard("总有功功率", zero, "kW", "无", null, now));
        defaults.add(createCard("电缆最高温度", zero, "℃", "无", "无", now));
        defaults.add(createCard("变压器温度", zero, "℃", "无", "无", now));

        KpiCardDTO alarmCard = new KpiCardDTO();
        alarmCard.setTitle("当前告警数");
        alarmCard.setValue(zero);
        alarmCard.setUnit("条");
        alarmCard.setDeviceName("系统");
        alarmCard.setSuffix("正常");
        alarmCard.setTimestamp(now);
        defaults.add(alarmCard);

        defaults.add(createCard("环境温度", zero, "℃", "无", null, now));

        return defaults;
    }

    @Override
    public DashboardKpiDTO getDashboardKpi(String orgId) {
        DashboardKpiDTO result = new DashboardKpiDTO();

        // C01: 10kV 仪表
        PowerMeterKpiDTO pm10kv = baseMapper.selectPowerMeter10kvKpi(orgId);
        result.setPowerMeter10kv(pm10kv != null ? pm10kv : PowerMeterKpiDTO.empty());

        // C02: 0.4kV 仪表
        PowerMeterKpiDTO pm04kv = baseMapper.selectPowerMeter04kvKpi(orgId);
        result.setPowerMeter04kv(pm04kv != null ? pm04kv : PowerMeterKpiDTO.empty());

        // C03: 微机保护异常数
        result.setMicroRelayAbnormalCount(baseMapper.selectMicroRelayAbnormalCount(orgId));

        // C04: 变压器温度
        TransformerTempKpiDTO temp = baseMapper.selectTransformerMaxTemp(orgId);
        result.setTransformerMaxTemp(temp != null ? temp : TransformerTempKpiDTO.empty());

        // C05: 环境告警数
        result.setEnvAlarmCount(baseMapper.selectEnvAlarmCount(orgId));

        // C06: 活跃设备总数
        result.setActiveDeviceCount(baseMapper.selectActiveDeviceCount(orgId));

        return result;
    }

    /**
     * 统计配电房、配电箱和设备的数量
     */
    @Override
    public Map<String, Object> getCounts(String orgId) {
        LambdaQueryWrapper<ElectricalRoom> electricalRoomWrapper = new LambdaQueryWrapper<>();
        electricalRoomWrapper.eq(ElectricalRoom::getOrgId, orgId);
        Long roomCount = electricalRoomMapper.selectCount(electricalRoomWrapper);

        LambdaQueryWrapper<SwitchCabinet> switchCabinetWrapper = new LambdaQueryWrapper<>();
        switchCabinetWrapper.eq(SwitchCabinet::getOrgId, orgId);
        Long cabinetCount = switchCabinetMapper.selectCount(switchCabinetWrapper);

        LambdaQueryWrapper<DeviceInstance> deviceInstanceMonitoringWrapper = new LambdaQueryWrapper<>();
        deviceInstanceMonitoringWrapper.eq(DeviceInstance::getOrgId, orgId);
        deviceInstanceMonitoringWrapper.eq(DeviceInstance::getDeviceType, "monitoring");
        Long deviceInstanceMonitoringCount = deviceInstanceMapper.selectCount(deviceInstanceMonitoringWrapper);

        LambdaQueryWrapper<DeviceInstance> deviceInstanceAcquisitionWrapper = new LambdaQueryWrapper<>();
        deviceInstanceAcquisitionWrapper.eq(DeviceInstance::getOrgId, orgId);
        deviceInstanceAcquisitionWrapper.ne(DeviceInstance::getDeviceType, "monitoring");
        Long deviceInstanceAcquisitionWrapperCount = deviceInstanceMapper.selectCount(deviceInstanceAcquisitionWrapper);

        LambdaQueryWrapper<DeviceInstance> deviceInstanceOnlineWrapper = new LambdaQueryWrapper<>();
        deviceInstanceOnlineWrapper.eq(DeviceInstance::getOrgId, orgId);
        deviceInstanceOnlineWrapper.eq(DeviceInstance::getStatus, "online");
        Long deviceInstanceOnlineCount = deviceInstanceMapper.selectCount(deviceInstanceOnlineWrapper);

        LambdaQueryWrapper<DeviceInstance> deviceInstanceOfflineWrapper = new LambdaQueryWrapper<>();
        deviceInstanceOfflineWrapper.eq(DeviceInstance::getOrgId, orgId);
        deviceInstanceOfflineWrapper.eq(DeviceInstance::getStatus, "offline");
        Long deviceInstanceOfflineCount = deviceInstanceMapper.selectCount(deviceInstanceOfflineWrapper);
        Map<String, Object> result = new HashMap<>();
        result.put("roomCount", roomCount);// 配电房
        result.put("cabinetCount", cabinetCount);// 配电箱
        result.put("deviceInstanceMonitoringCount", deviceInstanceMonitoringCount);// 监控 设备
        result.put("deviceInstanceAcquisitionWrapperCount", deviceInstanceAcquisitionWrapperCount);// 采集 设备
        result.put("deviceInstanceOnlineCount", deviceInstanceOnlineCount);// 在线 设备
        result.put("deviceInstanceOfflineCount", deviceInstanceOfflineCount);// 离线 设备
        return result;
    }

    //企业大屏中央统计数据
    @Override
    public Map<String, Object> getEnterpriseDashboardData(String orgId) {
        return null;
    }
}
